package com.boot.controller;

import com.boot.annotation.RateLimit;
import com.boot.entity.Question;
import com.boot.service.IAttachmentService;
import com.boot.service.IQuestionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * <p>
 * 附件表，用于存储与问题关联的上传文件信息 前端控制器
 * </p>
 *
 * @author bbyh
 * @since 2025-10-31
 */
@RestController
@RequestMapping("/api/attachment")
@Slf4j
public class AttachmentController {
    @Resource
    private IQuestionService questionService;

    @Resource
    private IAttachmentService attachmentService;

    @RateLimit(limit = 10, windowSec = 60)
    @GetMapping("/download/{questionId}")
    public ResponseEntity<StreamingResponseBody> downloadAttachments(@PathVariable Long questionId) {
        try {
            Question question = questionService.getById(questionId);
            if (question == null) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(out -> out.write("问题不存在".getBytes(StandardCharsets.UTF_8)));
            }

            String filename = "attachments_" + questionId + ".zip";
            String encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");

            HttpHeaders headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment", encodedFilename);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            StreamingResponseBody streamingBody = outputStream -> attachmentService.streamDownloadAttachmentsAsZip(questionId, outputStream);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(streamingBody);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/image/{imageName}")
    @RateLimit(limit = 60, windowSec = 60)
    public ResponseEntity<StreamingResponseBody> serveImage(@PathVariable String imageName) {
        try {
            return attachmentService.serveImage(imageName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
}
